/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainControlPanel.java
 *
 * Created on 2011/12/29, 下午 06:17:15
 */
package elaborate.tag_analysis.client.applications.delicious.ui;

import chrriis.dj.nativeswing.swtimpl.NativeInterface;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;
import chrriis.dj.nativeswing.swtimpl.components.MozillaXPCOM;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserCommandEvent;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserEvent;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserListener;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserNavigationEvent;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserWindowOpeningEvent;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserWindowWillOpenEvent;
import elaborate.tag_analysis.client.applications.ApplicationContext;
import elaborate.tag_analysis.client.MainFrame;
import elaborate.tag_analysis.client.TagEntry;
import elaborate.tag_analysis.client.event.TagProcessingEvent;
import elaborate.tag_analysis.client.event.TagProcessingEventType;
import elaborate.tag_analysis.client.utils.resource_logs.ResourceLogs;
import elaborate.task.TaskQueue;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import org.mozilla.interfaces.nsIDOMDocument;
import org.mozilla.interfaces.nsIDOMNamedNodeMap;
import org.mozilla.interfaces.nsIDOMNode;
import org.mozilla.interfaces.nsIDOMNodeList;
import org.mozilla.interfaces.nsIDOMWindow;
import org.mozilla.interfaces.nsIWebBrowser;
import org.w3c.dom.Node;

/**
 *
 * @author lendle
 */
public class MainControlPanel extends javax.swing.JPanel {

    private JWebBrowser browser = null;
    protected JTable tableTags;
    protected JTree treeResources;
    private URL workingURL = null;
    protected TaskQueue taskQueue;
    protected ResourceLogs resourceLogs;
    protected ApplicationContext context;
    
    
    
    /**
     * Get the value of context
     *
     * @return the value of context
     */
    public ApplicationContext getContext() {
        return context;
    }

    /**
     * Set the value of context
     *
     * @param context new value of context
     */
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    /**
     * Get the value of resourceLogs
     *
     * @return the value of resourceLogs
     */
    public ResourceLogs getResourceLogs() {
        return resourceLogs;
    }

    /**
     * Set the value of resourceLogs
     *
     * @param resourceLogs new value of resourceLogs
     */
    public void setResourceLogs(ResourceLogs resourceLogs) {
        this.resourceLogs = resourceLogs;
    }

    /**
     * Get the value of taskQueue
     *
     * @return the value of taskQueue
     */
    public TaskQueue getTaskQueue() {
        return taskQueue;
    }

    /**
     * Set the value of taskQueue
     *
     * @param taskQueue new value of taskQueue
     */
    public void setTaskQueue(TaskQueue taskQueue) {
        this.taskQueue = taskQueue;
    }

    /**
     * Get the value of treeResources
     *
     * @return the value of treeResources
     */
    public JTree getTreeResources() {
        return treeResources;
    }

    /**
     * Set the value of treeResources
     *
     * @param treeResources new value of treeResources
     */
    public void setTreeResources(JTree treeResources) {
        this.treeResources = treeResources;
    }

    /**
     * Get the value of tableTag
     *
     * @return the value of tableTag
     */
    public JTable getTableTags() {
        return tableTags;
    }

    /**
     * Set the value of tableTag
     *
     * @param tableTag new value of tableTag
     */
    public void setTableTags(JTable tableTag) {
        this.tableTags = tableTag;
    }

    /** Creates new form MainControlPanel */
    public MainControlPanel() {
        NativeInterface.open();
        Thread t = new Thread() {

            public void run() {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                    Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
                }

                NativeInterface.runEventPump();
            }
        };
        t.start();
        initComponents();
        System.setProperty("nativeswing.webbrowser.xulrunner.home", new File("xulrunner-3.6.23.en-US.win32\\xulrunner").getAbsolutePath());
        browser = new JWebBrowser(JWebBrowser.useXULRunnerRuntime());
        this.add(browser);
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    browser.navigate(new File("applications\\delicious\\DeliciousApplication.html").toURI().toURL().toString());
                } catch (MalformedURLException ex) {
                    Logger.getLogger(MainControlPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
                browser.addWebBrowserListener(new WebBrowserListener() {

                    @Override
                    public void windowWillOpen(WebBrowserWindowWillOpenEvent wbwwoe) {
                    }

                    @Override
                    public void windowOpening(WebBrowserWindowOpeningEvent wbwoe) {
                    }

                    @Override
                    public void windowClosing(WebBrowserEvent wbe) {
                    }

                    @Override
                    public void locationChanging(WebBrowserNavigationEvent wbne) {
                    }

                    @Override
                    public void locationChanged(WebBrowserNavigationEvent wbne) {
                    }

                    @Override
                    public void locationChangeCanceled(WebBrowserNavigationEvent wbne) {
                    }

                    @Override
                    public void loadingProgressChanged(WebBrowserEvent wbe) {
                        //System.out.println(wbe.getWebBrowser().getLoadingProgress());
                        if (wbe.getWebBrowser().getLoadingProgress() == 100) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException ex) {
                                Logger.getLogger(MainControlPanel.class.getName()).log(Level.SEVERE, null, ex);
                            }
                            nsIWebBrowser iWebBrowser = MozillaXPCOM.getWebBrowser(wbe.getWebBrowser());
                            //System.out.println("iWebBrowser="+iWebBrowser);
                            if (iWebBrowser == null) {
                                JOptionPane.showMessageDialog(browser, "The XPCOM nsIWebBrowser interface could not be obtained.\nPlease check your XULRunner configuration.", "XPCOM interface", JOptionPane.ERROR_MESSAGE);
                                return;
                            }
                            txStatus.setText("Connected to " + workingURL);
                            inspectBrowserContent(iWebBrowser);
                        }
                    }

                    @Override
                    public void titleChanged(WebBrowserEvent wbe) {
                    }

                    @Override
                    public void statusChanged(WebBrowserEvent wbe) {
                        //System.out.println(wbe.getWebBrowser().);
                    }

                    @Override
                    public void commandReceived(WebBrowserCommandEvent wbce) {
                    }
                });
            }
        });

    }

    public void extractTags(String urlString) {
        try {
            final URL url = new URL(urlString);
            workingURL = url;
            SwingUtilities.invokeAndWait(new Runnable() {

                @Override
                public void run() {
                    try {
                        txStatus.setText("Connecting to " + url + "......");
                        browser.navigate("http://www.delicious.com/url?url=" + URLEncoder.encode("" + url.getHost(), "utf-8"));
                    } catch (UnsupportedEncodingException ex) {
                        Logger.getLogger(MainControlPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });

        } catch (Exception ex) {
            Logger.getLogger(MainControlPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void inspectBrowserContent(nsIWebBrowser iWebBrowser) {
        nsIDOMWindow window = iWebBrowser.getContentDOMWindow();
        nsIDOMDocument document = window.getDocument();
        //nsIDOMNSHTMLDocument nsDocument = (nsIDOMNSHTMLDocument) document.queryInterface(nsIDOMNSHTMLDocument.NS_IDOMNSHTMLDOCUMENT_IID);
        //System.out.println(document.getDocumentElement());
        nsIDOMNodeList nodeList = document.getDocumentElement().getElementsByTagName("div");
        List<String> tags = new ArrayList<String>();
        outer:
        for (int i = 0; i < nodeList.getLength(); i++) {
            nsIDOMNode node = nodeList.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                nsIDOMNamedNodeMap attrs = node.getAttributes();
                for (int j = 0; j < attrs.getLength(); j++) {
                    nsIDOMNode attr = attrs.item(j);
                    if (attr.getNodeName().equals("id") && attr.getNodeValue().equals("tagcloud")) {
                        extractTags(tags, node);
                        break outer;
                    }
                }
            }
        }
        List<TagEntry> tagEntries = new ArrayList<TagEntry>();
        for (String tag : tags) {
            tagEntries.add(new TagEntry(tag));
        }

        if (workingURL != null) {
            TagProcessingEvent event = new TagProcessingEvent();
            event.setResourceIdentifier(this.workingURL.toString());
            event.setTagEntries(tagEntries.toArray(new TagEntry[0]));
            context.fireTagProcessingEvent(TagProcessingEventType.TAG_EXTRACTED, event);
        }
    }

    private void extractTags(List<String> tags, nsIDOMNode node) {
        //System.out.println(node.getNodeName() + ":" + node.getNodeType());
        if (node.getNodeName().toLowerCase().equals("a")) {
            String tag = node.getFirstChild().getNodeValue();
            if (tags.contains(tag) == false) {
                tags.add(tag);
            }
            //System.out.println(node.getFirstChild().getNodeValue());
        } else {
            nsIDOMNode child = node.getFirstChild();
            while (child != null) {
                extractTags(tags, child);
                child = child.getNextSibling();
            }
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        btReset = new javax.swing.JButton();
        txStatus = new javax.swing.JTextField();

        setLayout(new java.awt.BorderLayout());

        btReset.setText("Reset");
        jPanel1.add(btReset);

        add(jPanel1, java.awt.BorderLayout.SOUTH);

        txStatus.setEditable(false);
        add(txStatus, java.awt.BorderLayout.NORTH);
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btReset;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JTextField txStatus;
    // End of variables declaration//GEN-END:variables
}
